package com.qgs.rabbitmqapi.exchange.direct;

import com.rabbitmq.client.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * @Author: 蔡翔
 * @Date: 2019/7/15 13:29
 * @Version 1.0
 */

public class Consumer {
    public static void main(String[] args) throws Exception {
        //只要已启动consumer 那么队列和交换机 和通道就已经建立了。


        Logger logger = LoggerFactory.getLogger(Consumer.class);

        //1.创建一个ConnectionFactory,并进行配置
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.0.229"); //直接填地址不要 http://192.168.0.229
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        connectionFactory.setAutomaticRecoveryEnabled(true); //是否支持自动重连
        connectionFactory.setNetworkRecoveryInterval(3000);  //每隔3s执行一次重新连接


        //2.通过连接工厂创建连接
        Connection connection = connectionFactory.newConnection();

        //3.通过connection创建一个Channel
        Channel channel = connection.createChannel();

        //4.声明
        String exchangeName = "test_direct_exchange";
        String exchangeType = "direct";     //指定exchange的模式为direct
        String queueName="test_direct_queue";
        String routingKey = "test.direct";
        //声明了一个交换机
        channel.exchangeDeclare(exchangeName,exchangeType,true,false,false,null);
        //声明一个队列
        channel.queueDeclare(queueName,false,false,false,null);

        //使交换机和队列  建立一个绑定关系。
        channel.queueBind(queueName,exchangeName,routingKey);


        //5.创建消费者
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
            @Override   //这里DefaultConsumer 有一个好处就是会自动监听队列的里面的所有数据而不是 nextDelivery()
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                super.handleDelivery(consumerTag, envelope, properties, body);
                String messgae = new String(body,"UTF-8");
                logger.info("客户端接收到的数据是："+messgae);
                try {
                    Thread.sleep(10000);
                }catch (Exception e){

                }

                /*logger.info("consumerTag："+consumerTag);
                logger.info("properties："+properties);
                logger.info("envelope："+envelope); //对data的封装 打包成一个包，里面有很多信息，比如消息的标签，什么交换机，都有。*/
            }
        };


        //6.设置channel
        //basicConsume(String queue, boolean autoAck, Consumer callback);ack是当客户端取到一条message后会回送给broker一条信息表明收到，
        // autoAck表明自动签收；callback 就是具体的消费者对象了
        channel.basicConsume(queueName,true,defaultConsumer);

    }

}
